/**
 *   This file is part of WiFiStorer.

    WiFiStorer is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    WiFiStorer is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with WiFiStorer.  If not, see <http://www.gnu.org/licenses/>.
    
    @author Ontic Soluciones
    @license GNU GPLv3
    @copyright 2010 Ontic Soluciones
    @link http://www.ontic.es
    @contact android@ontic.es
 */

package com.Storer;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.text.Html;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;


/**
 * Activity principal, se encarga de comprobar si están activados la WIFI y el GPS y realiza escaneos cada
 * segundo o cada variación de 3m en la posición. Introduce los datos en la base de datos y crea el menú
 * que nos permite ejecutar las distintas actividades de la aplicación.
 * @author Ontic Soluciones
 *
 */
public class Principal extends Activity implements LocationListener
{
	private WifiManager wifi;
	private TextView textWifi;
	private TextView textGPS;
	private List<ScanResult> scan;
	private ArrayList<String> networks = new ArrayList<String>();
	private double lat, lng, alt ;
	private SQLiteDatabase DB = null;
	private String[] string = new String[4];
	private LocationManager lm = null;
	private String fecha;
	private Context context;
	private SimpleDateFormat formato = new SimpleDateFormat("yyyyMMdd");
	
	/** Se le llama cuando se crea la actividad.
	 * comprueba si están activados la WIFI y el servicio de GPS, si no lo están, lanza una actividad
	 * para que el usuario lo active o no.
	 * También crea la base de datos si ésta no existe e inicializa las vistas de texto. */
	@Override
	public void onCreate(Bundle savedInstanceState) 
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
		context = this;
		
	      /* Abrimos la base de datos.
	       * Si no existía previamente se creará automáticamente. */
		
		DataBaseHelper db = new DataBaseHelper(this);
		DB = db.getReadableDatabase();
		
		fecha ="" +formato.format(new java.util.Date());
	    DB = this.openOrCreateDatabase("Datos", 1, null);
	    DB.execSQL("create table if not exists t"+fecha +" (_id integer primary key autoincrement, lat int, lng int, alt real, SSID text, BSSID text, pow integer, prot text);");
		textWifi = (TextView) findViewById(R.id.textStatus);
		textGPS= (TextView) findViewById(R.id.textGPS);
		
		// Configuramos la WiFi
		wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);

		
		
		if(!wifi.isWifiEnabled())
		{
			startActivity(new Intent(Principal.this, PreguntaWifi.class));	
		}		

		lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000,3, (LocationListener) this);

	    if ( !lm.isProviderEnabled( LocationManager.GPS_PROVIDER ) ) 
	    {
			startActivity(new Intent(Principal.this,PreguntaGPS.class));
	    }			
	    else
	    {
	    	Context context = getApplicationContext();
			CharSequence text = this.getString(R.string.active_GPS);
			int duration = Toast.LENGTH_SHORT;
			
			textWifi.setText(Html.fromHtml("<hr><b><i>"+this.getString(R.string.GPS_signal)+"</i></b>"));
			
	    	Toast toast = Toast.makeText(context, text, duration);
			toast.setGravity(Gravity.CENTER, toast.getXOffset() / 2, toast.getYOffset() / 2);
			toast.show();
	    }
	    DB.close();
	    
	}
	
	/**
	 * Crea el menú de opciones que se mostrará cuando pulsamos el botón en el terminal
	 */
	public boolean onCreateOptionsMenu(Menu menu) 
	{
        menu.add(0, 1, 0,R.string.kml).setIcon(android.R.drawable.ic_menu_edit);
        menu.add(0, 2, 0, R.string.draw_map).setIcon(android.R.drawable.ic_menu_mapmode);
        menu.add(0, 4, 0, R.string.sendKml).setIcon(android.R.drawable.ic_dialog_email);
        menu.add(0, 3, 0, R.string.help).setIcon(android.R.drawable.ic_input_get);
        
        return(super.onCreateOptionsMenu(menu));
    }

	
/**
 * Detecta qué opción se ha elegido y lanza la actividad correspondiente.
 */
	@Override
	public boolean onOptionsItemSelected(MenuItem item) 
	{
	    switch (item.getItemId()) 
	    {
		    case 1:
		    	Intent i = new Intent(context, ListaKml.class);
		        startActivity(i);
		        break;
		        
		    case 2:
		    	Intent intent = new Intent(Principal.this,PintaMapa.class);
				startActivity(intent);
				break;
				
		    case 3: 
		    	Intent in = new Intent(Principal.this, About.class);
		    	startActivity(in);
		    	break;
		    	
		    case 4: 
		    	Intent inte = new Intent(Principal.this, SendKml.class);
		    	startActivity(inte);
		    	break;
		    	
		    default:
		        return super.onOptionsItemSelected(item);
		    }
			return false;
	}
	
	/**
	 * Se ejecuta cuando la actividad pasa a estado 'detenida'.
	 */
	public void onStop() 
	{
		super.onStop();
	}

	/**
	 * Se ejecuta cuando la actividad pasa a estado 'pausada'.
	 */
	public void onPause()
	{
		super.onPause();
	}
	
	/**
	 * Se ejecuta cuando el GPS detecta una variación en la posición, realiza el escaneo de la wifi,
	 * muestra la precisión actual, muestra los resultados del escaneo y los guarda en la tabla del día,
	 * si la precisión es mejor que 32 metros.
	 * Crea una nueva tabla si no existía la del día.
	 */
	@Override
	public void onLocationChanged(Location location) 
    {
    	wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
	    if (location != null)
	    {	    	
			textWifi.setText("");
			textGPS.setText(Html.fromHtml("<br><b>"+this.getString(R.string.accuracy)+": "+location.getAccuracy()+"m"+"</b><br><br>"));
			
			DataBaseHelper db = new DataBaseHelper(this);
			DB = db.getReadableDatabase();
	    				 
			DB.execSQL("create table if not exists t"+fecha +
					" (_id integer primary key autoincrement, lat int, lng int,"+
					" alt real, SSID text, BSSID text, pow integer, prot text);");
			
			double latitud = location.getLatitude();
			double longitud = location.getLongitude();
			  
		    lat = (int)(latitud*1000000);
		    lng = (int)(longitud*1000000);
		    alt = location.getAltitude();
		    
		    Geocoder geo = new Geocoder(this);
			Address address = null;
		    String currentLocation="";
		    String calle, ciudad = " ";
		    
			try {
				address = geo.getFromLocation(latitud, longitud, 1).get(0);
				calle = address.getAddressLine(0);
				ciudad = address.getAddressLine(1);
			} catch (IOException e) 
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
				//currentLocation = "Location unknown";
				calle = "Lat: "+ latitud;
				ciudad = "Long: "+ longitud;
				
				calle = calle.substring(0, 11);
				ciudad = ciudad.substring(0,12);
			}
		    
		    currentLocation = this.getString(R.string.location)+
				" "+calle+", "+ciudad;
		    
				textGPS.append("\n");
 
		    networks = new ArrayList<String>();
		    
		    wifi.startScan();
		    scan = wifi.getScanResults();
				
		    textGPS.append(Html.fromHtml("<b>"+currentLocation+"</b>"));
		    
		    textGPS.append("\n");
			    
			if(location.getAccuracy()<32 && location.getAccuracy()>0 && wifi.isWifiEnabled()) 
			{
				  textWifi.append(Html.fromHtml("<big><i>"+this.getString(R.string.accespoints)+":</i></big><br>"));
				  boolean par = true;
			      for (ScanResult config : scan) 
			      {    
			    	  networks.add((String)config.toString());
			    	  this.pintaSSIDyPotencia(config,par);
			    	  	
			    	  par = !par;
			    	  
			    	  String sql = "select lat, lng, BSSID from t"+fecha+" where lat="+lat+" and lng="+lng+" and BSSID='"+string[1]+"'";
			    		 Cursor c;
			    	  c = DB.rawQuery(sql, null);
			    	  if(!c.moveToFirst()) //devuelve falso si el cursor está vacío
			    	  {
							DB.execSQL("INSERT INTO t"+fecha+" (lat, lng, alt,  SSID, BSSID , pow, prot) VALUES('"+lat+"','"+lng+"', '"+alt+"','"+string[0]+"','"+ string[1]+"'," +
									" '"+(new Integer(string[2]).intValue())+"','"+string[3]+"');" );
			    	  }
				  }	
			      DB.close();
			}
	    }   	    
    }
	
	/**
	 * Se ejecuta cuando el GPS está deshabilitado.
	 */
	@Override
	public void onProviderDisabled(String provider) 
	{
		Context context = getApplicationContext();
		CharSequence text = this.getString(R.string.inactive_GPS);
		int duration = Toast.LENGTH_SHORT;
		
    	Toast toast = Toast.makeText(context, text, duration);
		toast.setGravity(Gravity.CENTER, toast.getXOffset() / 2, toast.getYOffset() / 2);
		toast.show();
	}

	/**
	 * Se ejecuta cuando el GPS está habilitado.
	 */
	@Override
	public void onProviderEnabled(String provider) 
	{
		Context context = getApplicationContext();
		CharSequence text = this.getString(R.string.active_GPS);
		int duration = Toast.LENGTH_SHORT;
		
    	Toast toast = Toast.makeText(context, text, duration);
		toast.setGravity(Gravity.CENTER, toast.getXOffset() / 2, toast.getYOffset() / 2);
		toast.show();		
	}

	@Override
	public void onStatusChanged(String provider, int status, Bundle extras) 
	{	
	}
	
	
	/**
	 * Separa el string resultado del escaneo de wifis en varias partes para mostrarlas e introducirlas
	 * en la base de datos
	 * @param config El resultado del escaneo.
	 */
	private void pintaSSIDyPotencia(ScanResult config, boolean par) 
		{				
		  
			String cadena = config.toString();
			int inicio,fin;
			
			inicio = cadena.indexOf("SSID:");
			fin = cadena.indexOf(", BSS");
			String nombre = cadena.substring(inicio, fin);
			nombre = nombre.substring(5);
			
			inicio = cadena.indexOf("level: -");
			fin = cadena.indexOf(", freq", inicio);
			
			String potencia = cadena.substring(inicio, fin);	
			potencia = potencia.substring(8);
			
			inicio = cadena.indexOf("BSSID: ");
			fin = cadena.indexOf(", capabi", inicio);
			
			String mac = cadena.substring(inicio, fin);
			mac = mac.substring(7);
			
			inicio = cadena.indexOf("capabilities: ");
			fin = cadena.indexOf(", level", inicio);
			
			
			String capa = cadena.substring(inicio,fin);
			capa  = capa.substring(14);
			
			string[0] = nombre;
			string[1] = mac;
			string[2] = potencia;
			string[3] = capa;
			textWifi.append("\n-");
			if(par)
				textWifi.append(Html.fromHtml("<b><i>"+string[0]+" ["+string[1]+"],"+" -"+string[2]+"</b></i><br><br>"));
			else
				textWifi.append(Html.fromHtml("<b>"+string[0]+" ["+string[1]+"],"+" -"+string[2]+"</b><br><br>"));
		}

	  /**
	   * Devuelve Wifi 
	   * @return wifi Instancia de WifiManager
	   */
	  public WifiManager getWifi()
	  {
		  return wifi;
	  }
}
